/***
 * CaRComp Translator
 * 
 * Copyright (C) 2011 Taylor L. Riche
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ***/

grammar App;

options {
  language = Java;
}

@header {
  package translator.grammar;
  import translator.objects.*;
  import java.util.Map;
  import java.util.HashMap;
}

@lexer::header {
  package translator.grammar;
}

algo returns [Algorithm alg]
  @init {$alg = null;} 
  : ALGO_KW '(' ident=Q_LIT ',' name=Q_LIT ',' p_map=port_list ',' c_map=comp_list ',' cn_map=conn_list ')' 
  {
    $alg = new Algorithm($ident.getText(), $name.getText(), p_map, c_map, cn_map);
    //System.out.println(alg.getIdent());
    //for(Port p : p_map.values()) {
    //  System.out.println(p.getIdent());
    //}  
    //for(Component c : c_map.values()) {
    //  System.out.println(c.getIdent());
    //  c.printPorts();
    //}
    //for(Connector cn : cn_map.values()) {
    //  System.out.println(cn.getText());
    //}
  }
  ;

port_list returns [Map<String, Port> p_map]
  @init {$p_map = new HashMap<String, Port>();}
  : '[' (p=port{p_map.put(p.getIdent(), p);})+ ']' 
  ;
  
port returns [Port p]
  : direction=ID '(' ident=Q_LIT ',' name=Q_LIT ',' type=Q_LIT ')' (',')?
    {$p = new Port($ident.getText(), $name.getText(), $direction.getText(), $type.getText());}
  ;
 
comp_list returns [Map<String, Component> c_map]
  @init {$c_map = new HashMap<String, Component>();}
  : '[' (c=comp{c_map.put(c.getIdent(),c);})+ ']'
  ;
  
comp returns [Component c]
  : ABS_KW '(' ident=Q_LIT ',' name=Q_LIT ',' p_map=port_list ')' (',')?
    { $c = new Component($ident.getText(), $name.getText(), p_map);}
  ;
  
conn_list returns [Map<String, Connector> cn_map]
  @init {$cn_map = new HashMap<String, Connector>();}
  : '[' (cn=conn{cn_map.put(cn.getIdent(), cn);})+ ']'
  ;
  
conn returns [Connector cn]
  : CONN_KW '(' ident=Q_LIT ',' source=Q_LIT ',' destination=Q_LIT ')' (',')?
    { $cn = new Connector($ident.getText(), $source.getText(), $destination.getText());}
  ;
  
ALGO_KW : 'alg';
ABS_KW : 'abs';
CONN_KW : 'conn';
ID  :   ('a'..'z'|'A'..'Z'|'0'..'9')+;
Q_LIT : '"'(' '|'a'..'z'|'A'..'Z'|'0'..'9')+'"';
WS : (' '|'\t'|'\f'|'\n'|'\r')+{ $channel=HIDDEN; };